#pragma once
#include "BaseStack.h"
#include "LockHelper.h"

template <typename T>
class ConcurrentLinkedStack : public LinkedStack<T>
{
private :
	LockHelper m_oLockHelper;
public :
	ConcurrentLinkedStack(int a_nMaxSize);
	~ConcurrentLinkedStack();

	virtual void push(T a_oData);
	virtual T pop();
	virtual bool canPush();
	virtual bool canPop();
	virtual int getDataCount();

};

template <typename T>
ConcurrentLinkedStack<T>::ConcurrentLinkedStack(int a_nMaxSize) : LinkedStack<T>(a_nMaxSize)
{
}

template <typename T>
ConcurrentLinkedStack<T>::~ConcurrentLinkedStack()
{
}

template <typename T>
void ConcurrentLinkedStack<T>::push(T a_oData) 
{
	m_oLockHelper.lock();
	LinkedStack<T>::push(a_oData);
	m_oLockHelper.unlock();
}

template <typename T>
T ConcurrentLinkedStack<T>::pop() 
{
	m_oLockHelper.lock();
	T poppedValue = LinkedStack<T>::pop();
	m_oLockHelper.unlock();
	return poppedValue;
}

template <typename T>
bool ConcurrentLinkedStack<T>::canPush() 
{
	bool bRet = false;
	m_oLockHelper.lock();
	bRet = LinkedStack<T>::canPush();
	m_oLockHelper.unlock();
	return bRet;
}

template <typename T>
bool ConcurrentLinkedStack<T>::canPop() 
{
	bool bRet = false;
	m_oLockHelper.lock();
	bRet = LinkedStack<T>::canPop();
	m_oLockHelper.unlock();
	return bRet;
}

template <typename T>
int ConcurrentLinkedStack<T>::getDataCount()
{
	int dataCount = 0;
	m_oLockHelper.lock();
	dataCount = LinkedStack<T>::getDataCount();
	m_oLockHelper.unlock();
	return dataCount;
}